<?php
namespace Core\Libs\Util;

class Collections {

	
}

class RecursiveIterator implements \RecursiveIterator {

	private $data;
	private $position = 0;

	public function __construct(array $data) {

		$this->data = $data;
	}
    
	public function valid() {

		return isset($this->data[$this->position]);
	}
    
	public function hasChildren() {

		return is_array($this->data[$this->position]);
	}
    
	public function next() {

		$this->position++;
	}
    
	public function current() {

		return $this->data[$this->position];
	}
    
	public function getChildren() {

		$this->data[$this->position];
	}
    
	public function rewind() {

		$this->position = 0;
	}
    
	public function key() {

		return $this->position;
	}
}

class HashTable {

	
}

class HashMap {

	
}

class SendVar {

	
}

class SharedVar {

	
}

class String {

	final public static function insert($str, $data, $options = array()) {

		$defaults = array('before' => ':', 'after' => NULL, 'escape' => '\\', 'format' => NULL, 'clean' => FALSE);
		$options += $defaults;
		$format = $options['format'];
		$data = (array)$data;

		if(empty($data)) {

			return ($options['clean']) ? self::cleanInsert($str, $options) : $str;
		}

		if(!isset($format)) {

			$format = sprintf(
				'/(?<!%s)%s%%s%s/',
				preg_quote($options['escape'], '/'),
				str_replace('%', '%%', preg_quote($options['before'], '/')),
				str_replace('%', '%%', preg_quote($options['after'], '/'))
			);
		}

		if(strpos($str, '?') !== FALSE && is_numeric(key($data))) {

			$offset = 0;

			while (($pos = strpos($str, '?', $offset)) !== FALSE) {

				$val = array_shift($data);
				$offset = $pos + strlen($val);
				$str = substr_replace($str, $val, $pos, 1);
			}

			return ($options['clean']) ? self::cleanInsert($str, $options) : $str;
		}

		else {

			asort($data);
			$hashKeys = array();

			foreach($data as $key => $value) {

				$hashKeys[] = crc32($key);
			}

			$tempData = array_combine(array_keys($data), array_values($hashKeys));

			foreach($tempData as $key => $hashVal) {

				$key = sprintf($format, preg_quote($key, '/'));
				$str = preg_replace($key, $hashVal, $str);
			}

			$dataReplacements = array_combine($hashKeys, array_values($data));

			foreach($dataReplacements as $tmpHash => $tmpValue) {

				$tmpValue = (is_array($tmpValue)) ? '' : $tmpValue;
				$str = str_replace($tmpHash, $tmpValue, $str);
			}
		}

		if(!isset($options['format']) && isset($options['before'])) {

			$str = str_replace($options['escape'].$options['before'], $options['before'], $str);
		}

		return ($options['clean']) ? self::cleanInsert($str, $options) : $str;
	}

	final public static function cleanInsert($str, $options) {

		$clean = $options['clean'];

		if(!$clean) {

			return $str;
		}

		if($clean === TRUE) {

			$clean = array('method' => 'text');
		}

		if(!is_array($clean)) {

			$clean = array('method' => $options['clean']);
		}

		switch ($clean['method']) {

			case 'html':

				$clean = array_merge(array(
					'word' => '[\w,.]+',
					'andText' => TRUE,
					'replacement' => '',
				), $clean);

				$kleenex = sprintf(
					'/[\s]*[a-z]+=(")(%s%s%s[\s]*)+\\1/i',
					preg_quote($options['before'], '/'),
					$clean['word'],
					preg_quote($options['after'], '/')
				);

				$str = preg_replace($kleenex, $clean['replacement'], $str);

				if($clean['andText']) {

					$options['clean'] = array('method' => 'text');
					$str = self::cleanInsert($str, $options);
				}

				break;

			case 'text':

				$clean = array_merge(array(
					'word' => '[\w,.]+',
					'gap' => '[\s]*(?:(?:and|or)[\s]*)?',
					'replacement' => '',
				), $clean);

				$kleenex = sprintf(
					'/(%s%s%s%s|%s%s%s%s)/',
					preg_quote($options['before'], '/'),
					$clean['word'],
					preg_quote($options['after'], '/'),
					$clean['gap'],
					$clean['gap'],
					preg_quote($options['before'], '/'),
					$clean['word'],
					preg_quote($options['after'], '/')
				);

				$str = preg_replace($kleenex, $clean['replacement'], $str);
				break;
		}

		return $str;
	}
}
?>